home *** CD-ROM | disk | FTP | other *** search
/ Sun Solutions 1997 April to September / Sun Solutions CD - APR '97 - SEP '97 (704-3778-12 Rev. H)(Sun Microsystems, Inc.)(1997).iso / products / Hyperion / src / PORTING < prev    next >
Text File  |  1997-02-26  |  9KB  |  189 lines

  1. - @(#)PORTING    1.3 2/24/94 -
  2.  
  3. Porting WorkMan to a new platform is a two-step process.  The first step
  4. is to get the XView toolkit, version 3.0 or higher, running on your system.
  5. If you're lucky, someone else has already done so.  The alt.toolkits.xview
  6. and comp.windows.open-look newsgroups are good places to find out whether
  7. XView exists for your system.
  8.  
  9. Once you have XView installed, you can work on porting WorkMan itself.
  10. If your system has builtin libraries for manipulating audio CDs, you can
  11. use them.  Or you can use your system's user-level SCSI interface, if any.
  12. (Or both!)
  13.  
  14. All of the user interface modules ought to compile without modification.
  15. For the most part they're just standard C and documented XView calls.
  16.  
  17. The platform-dependent code in WorkMan is in source files named plat_xxx.c,
  18. where xxx is the platform name.  If you look at a directory listing you'll
  19. see that there are files like this for Sun, HP, Linux, and other platforms
  20. already.  Each of these files (called "platform modules") contains a set of
  21. well-defined functions for controlling and getting information from a CD-ROM
  22. drive.  You'll find a list of those functions below.  Ordinarily, porting
  23. WorkMan is simply a matter of writing those functions for your platform,
  24. and you can usually use one of the existing platform modules as a starting
  25. point.
  26.  
  27. WorkMan supports the notion of running any kind of drive on any platform,
  28. assuming the platform has facilities for sending arbitrary SCSI commands
  29. from user processes.  To this end, you'll also find "drive modules" named
  30. drv_xxx.c.  Each drive module contains replacement functions along the
  31. lines of the functions in the platform modules; these replacement functions
  32. are called when the drive doesn't respond to generic requests or when
  33. something unusual needs to be done.  For instance, the Sony CDU-8012 (also
  34. known as the SunCD drive) has a weird volume scale, so we need to do a
  35. transformation on the volume setting before passing it to the drive.  But
  36. other than that, the drive responds to generic CD-ROM commands, so
  37. drv_sony.c only has code relating to volume control.
  38.  
  39. Implementing drive modules is fairly simple, but usually isn't necessary
  40. so it won't be discussed here.  Mail me if you need to do it.
  41.  
  42. Here are the functions a platform module needs to implement.  All functions
  43. should return integers.  Unless otherwise noted, they should return 0 on
  44. okay status, -1 on an error condition.
  45.  
  46. The first parameter of each function is a pointer to a wm_drive structure.
  47. You'll find it defined in "struct.h".  It's discussed after the function call
  48. list.  You will probably find it helpful to look at one of the existing
  49. platform modules while reading this list.  The Sun module is one of the
  50. simpler ones.
  51.  
  52. wmcd_open(struct wm_drive *d)
  53.     Figure out the drive type and fill in pointers to the rest of the
  54.     routines listed here.  This routine should set up the device to
  55.     receive CD-ROM commands if necessary.  If the wm_drive structure
  56.     says the drive is already open, this routine should return 0 --
  57.     in other words, it shouldn't hurt to call wmcd_open ten times
  58.     in a row.  If the drive couldn't be opened yet, or initialization
  59.     couldn't be performed yet, the function should clean up and
  60.     return 1; it will be called again after a short delay.  A common
  61.     example is an open() call failing because there's no CD in the
  62.     drive.
  63.  
  64.     wmcd_open() should determine the drive type if possible.  If the
  65.     wm_scsi() function has been implemented, it can simply call
  66.     wm_scsi_get_drive_type() (which is in scsi.c) to retrieve the
  67.     necessary information.  Then find_drive_struct() (from cdrom.c)
  68.     should be called to look up the drive from the list of drive
  69.     modules; it returns a pointer to a wm_drive structure, which
  70.     should be copied into the buffer pointed to by the "d" parameter.
  71.     Finally, the drive init function should be called.
  72.     
  73.     Some systems can't determine the drive type at all, for instance
  74.     because the CD-ROM drive can only be accessed through a limited
  75.     set of function calls.  In that case, just pass empty strings
  76.     to find_drive_struct() and it'll return a wm_drive structure
  77.     pointing to the generic platform module routines.
  78.  
  79. wm_scsi(struct wm_drive *d, unsigned char *cdb, int cdblen,
  80.         unsigned char *buf, int len, int getdata)
  81.     Send a command to the SCSI device referenced by the wm_drive
  82.     structure.  A CDB of appropriate size is passed in, as is a data
  83.     buffer.  If "getdata" is true, read some data into the buffer in
  84.     response to the command.  Otherwise the buffer might contain some
  85.     data to be written out as part of the command.  "buf" can be
  86.     NULL if the caller doesn't want to pass in or receive any data.
  87.     Return -1 if the command doesn't complete successfully.  If your
  88.     system doesn't support SCSI passthrough, this function should just
  89.     return -1 without doing anything else.
  90.  
  91. The following functions can be overridden by drive modules, as they're
  92. always called indirectly via the wm_drive structure.
  93.  
  94. gen_init(struct wm_drive *d)
  95.     Initialize whatever drive-specific settings are required.  For the
  96.     platform module this is usually just { return (0); } since any
  97.     platform-specific initialization should be performed in wmcd_open(),
  98.     but the function needs to be defined.
  99.  
  100. gen_get_trackcount(struct wm_drive *d, int *tracks)
  101.     Store the number of tracks on the CD in *tracks.
  102.  
  103. gen_get_cdlen(struct wm_drive *d, int *frames)
  104.     Store the total number of frames on the CD in *frames.
  105.  
  106. gen_get_trackinfo(struct wm_drive *d, int track, int *data, int *startframe)
  107.     Get the starting frame number and type (1 = data track, 0 = audio) of
  108.     a particular track.  Tracks are numbered starting at 1, as on the CD.
  109.  
  110. gen_get_drive_status(struct wm_drive *d, enum mode oldmode, enum mode *mode,
  111.             int *pos, int *track, int *index)
  112.     Get the current status of the drive.  Mode is one of PLAYING, PAUSED,
  113.     TRACK_DONE, STOPPED, and EJECTED, as is oldmode (which will be the
  114.     previous mode value returned by the routine.)  The other parameters
  115.     are filled in if the drive is playing or paused: the absolute position
  116.     in frames, the track number, and the index number.
  117.  
  118. gen_get_volume(struct wm_drive *d, int *left, int *right)
  119.     Get the current volume settings for the left and right channels, or
  120.     -1 if that information can't be read from the drive.  Values range
  121.     from 0 to 100 on a linear scale.
  122.  
  123. gen_set_volume(struct wm_drive *d, int left, int right)
  124.     Set the current volume for each channel.  Values are from 0 to 100,
  125.     on the same linear scale as returned by gen_get_volume().
  126.  
  127. gen_pause(struct wm_drive *d)
  128.     Pause the CD.
  129.  
  130. gen_resume(struct wm_drive *d)
  131.     Resume playing the CD after a pause.
  132.  
  133. gen_stop(struct wm_drive *d)
  134.     Stop the CD if it's playing or paused.
  135.  
  136. gen_play(struct wm_drive *d, int start, int end)
  137.     Play a stretch of the CD.  Both times are in frames.  This can return
  138.     negative values other than -1 if playing a CD is a multi-step process,
  139.     e.g. a "start motor" command followed by a "play audio" command.
  140.  
  141. gen_eject(struct wm_drive *d)
  142.     Eject the CD.  Return -3 if the CD can't be ejected because it
  143.     contains a mounted filesystem.
  144.  
  145. The wm_drive structure has at least the following elements:
  146.  
  147. struct wm_drive {
  148.     int    fd;        /* File descriptor, if used by platform */
  149.     char    vendor[16];    /* Vendor name */
  150.     char    model[24];    /* Drive model */
  151.     void    *aux;        /* Pointer to optional platform-specific info */
  152.     void    *daux;        /* Pointer to optional drive-specific info */
  153.  
  154.     int    (*init)();
  155.     int    (*get_trackcount)();
  156.     int    (*get_cdlen)();
  157.     int    (*get_trackinfo)();
  158.     int    (*get_drive_status)();
  159.     int    (*get_volume)();
  160.     int    (*set_volume)();
  161.     int    (*pause)();
  162.     int    (*resume)();
  163.     int    (*stop)();
  164.     int    (*play)();
  165.     int    (*eject)();
  166. }
  167.  
  168. The "fd" and/or "aux" elements should be filled in by the wmcd_open()
  169. function after find_drive_struct() is called.  The "fd" element is for an
  170. open file descriptor pointing to the drive, though if your platform doesn't
  171. use file descriptors to refer to CD-ROM drives (e.g. the BSD/386 platform,
  172. whose CD library uses structure pointers) you can use the "fd" element for
  173. something else or ignore it completely.
  174.  
  175. The "aux" element should be used to point to any state information you
  176. need to keep across calls to these functions.  Since WorkMan may eventually
  177. support controlling multiple drives simultaneously, you should not use
  178. global variables to keep per-drive state.  Define a structure for whatever
  179. state you need, and point "aux" to it.  You can get at it in any of the
  180. routines since they are all passed the wm_drive structure you fill in in
  181. wmcd_open().  On many platforms, "aux" isn't needed.
  182.  
  183. The "daux" element is reserved for use in drive modules.
  184.  
  185. If you have questions, don't hesitate to send me E-mail.  I want to see
  186. WorkMan as widely ported as possible.
  187.  
  188. -Steven Grimm <koreth@hyperion.com>
  189.